#!/bin/bash
set -euo pipefail

# 初始化信息
echo "====================================="
echo "AstrBot 一键部署脚本"
echo "====================================="
echo "作者：iUARN"
echo ""
echo "此脚本可自动安装并配置以下服务："
echo "1. Docker 运行环境（含镜像源加速）"
echo "2. AstrBot - 多功能机器人平台（默认密码：astrbot）"
echo "3. Napcat - 配套管理工具（含WebUI密钥）"
echo ""
echo "安装要求："
echo "- 系统：Ubuntu/Debian"
echo "- 权限：当前用户（root用户除外）需有 sudo 权限"
echo ""
echo "默认访问地址："
echo "- AstrBot: http://服务器IP:6185"
echo "- Napcat: http://服务器IP:6099（需用日志生成的token登录）"
echo "====================================="

# 请求用户确认
read -rp "是否继续安装? (y/n): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then 
    echo "安装已取消"
    exit 0
fi

# 检查是否已安装docker
check_docker() {
    command -v docker &> /dev/null
}

# 显示安装选项
echo "请选择操作类型："
echo "1. 完整版安装 (Docker + AstrBot + Napcat) - 推荐新手"
echo "2. 仅安装 Docker 运行环境 - 仅需容器环境时选择"
echo "3. 安装 Docker 和 AstrBot - 无需Napcat时选择"
echo "4. 仅安装 Napcat - 适用于重新安装Napcat"
echo "5. 安装 AstrBot 和 Napcat - 已装Docker时选择"
echo "6. 更新 astrbot 或 napcat - 升级到最新版本"
read -rp "请输入选项 (1-6): " choice

# 检查Docker环境（针对需要Docker的选项）
if [[ "$choice" == "4" || "$choice" == "5" || "$choice" == "6" ]]; then
    if ! check_docker; then
        echo "错误：当前系统未安装 Docker，请先选择选项2安装 Docker 环境"
        exit 1
    fi
fi

# 安装Docker（含镜像源加速配置）
install_docker() {
    echo "====================================="
    echo "开始安装Docker环境..."
    
    # 实际安装操作
    sudo apt update -y
    sudo apt install -y docker.io
    sudo systemctl start docker
    sudo systemctl enable docker
    echo "Docker基础服务安装完成"
    
    # 配置镜像源
    echo "配置Docker镜像源加速..."
    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json >/dev/null <<EOF
{
  "registry-mirrors": [
    "https://hub.fast360.xyz",
    "https://hub.rat.dev",
    "https://docker.m.daocloud.io",
    "https://docker.1ms.run",
    "https://image.cloudlayer.icu"
  ]
}
EOF
    if sudo systemctl restart docker; then
        echo "Docker镜像源配置成功并重启完成"
    else
        echo "警告：Docker重启失败（可能部分镜像源不可用），不影响基础使用"
    fi
    echo "====================================="
}

# 安装AstrBot（新增：安装后提示默认密码）
install_astrbot() {
    local is_update="${1:-false}"  # 默认是全新安装，非更新

    echo "====================================="
    echo "开始配置AstrBot运行环境..."
    
    # 处理目录（更新时保留，全新安装时初始化）
    if [ "$is_update" = "false" ]; then
        if [ ! -d "astrbot" ]; then
            mkdir -p astrbot/data
            sudo chown -R $(id -u):$(id -g) astrbot/data
            echo "已创建AstrBot数据目录（路径：$PWD/astrbot/data）"
        else
            echo "AstrBot数据目录已存在（路径：$PWD/astrbot/data），将复用现有数据"
        fi
    else
        echo "更新模式：保留AstrBot现有数据目录"
    fi

    # 处理已有容器
    existing_container=$(docker ps -a --filter name=astrbot -q)
    if [ -n "$existing_container" ]; then
        read -rp "检测到已存在astrbot容器，是否删除旧容器后重新安装？(y/n): " del_confirm
        if [[ "$del_confirm" =~ ^[Yy]$ ]]; then
            docker rm -f "$existing_container"
            echo "旧astrbot容器已删除"
        else
            echo "安装终止（保留旧容器）"
            exit 1
        fi
    fi

    # 创建容器
    echo "拉取AstrBot镜像并创建容器..."
    sudo docker run -itd \
      --restart=always \
      -p 6180-6200:6180-6200 \
      -p 11451:11451 \
      -v "$PWD/astrbot/data:/AstrBot/data" \
      -v /etc/localtime:/etc/localtime:ro \
      -v /etc/timezone:/etc/timezone:ro \
      --name astrbot \
      soulter/astrbot:latest
    
    # 提示默认密码
    echo -e "\n====================================="
    echo -e "⚠️  【重要】AstrBot 默认登录信息"
    echo -e "====================================="
    echo -e "🔑 默认账号密码：astrbot"
    echo -e "====================================="
    echo -e "✅ 安全提示："
    echo -e "1. 访问AstrBot：http://服务器IP:6185"
    echo -e "2. 登录后请尽快修改默认密码，保障服务安全"
    echo -e "====================================="

    echo "AstrBot安装/更新完成！"
    echo "====================================="
}

# 安装Napcat（支持全新安装/更新，保留数据）
install_napcat() {
    local is_update="${1:-false}"  # 默认是全新安装，非更新

    echo "====================================="
    echo "开始安装/更新Napcat管理工具..."
    
    # 处理数据目录（更新时保留，全新安装时初始化）
    if [ "$is_update" = "false" ]; then
        if [ -d "$PWD/napcat" ]; then
            echo "检测到已有Napcat目录（全新安装模式），删除并重建..."
            sudo rm -rf "$PWD/napcat"
        fi
    else
        echo "更新模式：保留Napcat现有数据目录"
    fi
    mkdir -p "$PWD/napcat"
    sudo chown -R $(id -u):$(id -g) "$PWD/napcat"
    echo "已准备Napcat数据目录（路径：$PWD/napcat）"

    # 处理已有容器
    existing_container=$(docker ps -a --filter name=napcat -q)
    if [ -n "$existing_container" ]; then
        read -rp "检测到已存在napcat容器，是否删除旧容器后重新安装？(y/n): " del_confirm
        if [[ "$del_confirm" =~ ^[Yy]$ ]]; then
            docker rm -f "$existing_container"
            echo "旧napcat容器已删除"
        else
            echo "操作终止（保留旧容器）"
            exit 1
        fi
    fi

    # 拉取镜像并创建容器
    echo "拉取Napcat镜像并创建容器..."
    docker run -d \
      -e NAPCAT_GID=$(id -g) \
      -e NAPCAT_UID=$(id -u) \
      -p 3000:3000 \
      -p 3001:3001 \
      -p 6099:6099 \
      -v "$PWD/napcat:/app/data" \
      -v /etc/localtime:/etc/localtime:ro \
      --name napcat \
      --restart=always \
      mlikiowa/napcat-docker:latest
    
    #等待容器启动
    echo "等待Napcat容器完全启动（最多等待10秒）..."
    container_started=false
    for i in {1..10}; do
        if docker ps --filter name=napcat --filter status=running -q &> /dev/null; then
            echo "Napcat容器已成功启动（耗时 ${i} 秒）"
            container_started=true
            break
        fi
        echo "等待中...（${i}/10）"
        sleep 1
    done

    if [ "$container_started" = "false" ]; then
        echo "错误：Napcat容器启动超时，请执行 'docker logs napcat' 检查日志"
        exit 1
    fi

    #多次重试提取token
    set +e  # 临时关闭 set -e，允许命令失败，后续手动判断结果
    echo "正在提取Napcat WebUI鉴权token（最多尝试3次）..."
    napcat_token=""
    for attempt in {1..3}; do
        napcat_token=$(docker logs napcat 2>&1 | grep "🔑 token=" | sed 's/.*🔑 token=//')
        if [ -n "$napcat_token" ]; then
            break
        fi
        echo "第 ${attempt} 次提取失败，将在5秒后重试..."
        sleep 5 #修改到5秒，确保日志生成
    done
    set -e  # 恢复严格错误检查

    # 处理token提取结果（无论成功/失败，都强制输出后续内容）
    if [ -n "$napcat_token" ]; then
        echo -e "\n====================================="
        echo -e "⚠️  【重要】Napcat WebUI鉴权token"
        echo -e "====================================="
        echo -e "🔑 您的Napcat登录token：\033[31m$napcat_token\033[0m"
        echo -e "====================================="
        echo -e "✅ 使用说明："
        echo -e "1. 访问Napcat：http://服务器IP:6099"
        echo -e "2. 输入上方token完成鉴权（token仅在首次启动生成，建议保存）"
        echo -e "3. 若token丢失：执行命令查看日志：docker logs napcat | grep '🔑 token='"
        echo -e "====================================="
    else
        echo -e "\n⚠️  警告：多次尝试后仍未提取到Napcat token"
        echo "请手动执行以下命令查看token："
        echo "docker logs napcat | grep '🔑 token='"
    fi

    sleep 2  # 确保输出完全刷新
    echo "Napcat安装/更新完成！"
    echo "====================================="
}

# 更新AstrBot（保留数据，调用install_astrbot并传is_update=true）
update_astrbot() {
    echo "====================================="
    echo "开始更新AstrBot到最新版本..."
    
    # 停止并删除现有容器（保留数据目录）
    existing_container=$(docker ps -a --filter name=astrbot -q)
    if [ -n "$existing_container" ]; then
        echo "停止并删除现有AstrBot容器..."
        docker stop "$existing_container"
        docker rm -f "$existing_container"
    fi
    
    # 拉取最新镜像
    echo "拉取最新的AstrBot镜像..."
    docker pull soulter/astrbot:latest
    
    # 调用install_astrbot，传入is_update=true（保留数据目录）
    install_astrbot "true"
}

# 更新Napcat（保留数据，调用install_napcat并传is_update=true）
update_napcat() {
    echo "====================================="
    echo "开始更新Napcat到最新版本..."
    
    # 停止并删除现有容器（保留数据目录）
    existing_container=$(docker ps -a --filter name=napcat -q)
    if [ -n "$existing_container" ]; then
        echo "停止并删除现有Napcat容器..."
        docker stop "$existing_container"
        docker rm -f "$existing_container"
    fi
    
    # 拉取最新镜像
    echo "拉取最新的Napcat镜像..."
    docker pull mlikiowa/napcat-docker:latest
    
    # 调用install_napcat，传入is_update=true（保留数据目录）
    install_napcat "true"
}

# 处理更新选项
handle_update() {
    echo "请选择要更新的服务："
    echo "1. AstrBot"
    echo "2. Napcat"
    read -rp "请输入选项 (1-2): " update_choice
    
    case $update_choice in
        1)
            update_astrbot
            ;;
        2)
            update_napcat
            ;;
        *)
            echo "错误：无效选项，更新已取消"
            exit 1
            ;;
    esac
}

# 根据用户选择执行对应操作流程
case $choice in
    1)
        echo "您选择了【完整版安装】"
        install_docker
        install_astrbot
        install_napcat
        ;;
    2) 
        echo "您选择了【仅安装 Docker】"
        install_docker 
        ;;
    3)
        echo "您选择了【安装 Docker 和 AstrBot】"
        install_docker
        install_astrbot
        ;;
    4)
        echo "您选择了【仅安装 Napcat】"
        install_napcat
        ;;
    5)
        echo "您选择了【安装 AstrBot 和 Napcat】"
        install_astrbot
        install_napcat
        ;;
    6)
        echo "您选择了【更新 astrbot 或 napcat】"
        handle_update
        ;;
    *)
        echo "错误：无效选项（仅支持 1-6），操作已取消"
        exit 1
        ;;
esac

# 输出最终使用提示
echo "====================================="
echo "操作全部完成！当前状态："
case $choice in
    1)
        echo "- Docker 运行环境（已配置镜像加速）"
        echo "- AstrBot: http://服务器IP:6185（默认账号密码：astrbot，建议登录后修改）"
        echo "- Napcat: http://服务器IP:6099（已生成token，见上方输出）"
        ;;
    2) 
        echo "- Docker 运行环境（已配置镜像加速）"
        ;;
    3) 
        echo "- Docker 运行环境（已配置镜像加速）"
        echo "- AstrBot: http://服务器IP:6185（默认账号密码：astrbot，建议登录后修改）"
        ;;
    4) 
        echo "- Napcat: http://服务器IP:6099（已生成token，见上方输出）"
        ;;
    5) 
        echo "- AstrBot: http://服务器IP:6185（默认账号密码：astrbot，建议登录后修改）"
        echo "- Napcat: http://服务器IP:6099（已生成token，见上方输出）"
        ;;
    6)
        if [ "$update_choice" = "1" ]; then
            echo "- AstrBot 已更新至最新版本: http://服务器IP:6185"
        else
            echo "- Napcat 已更新至最新版本: http://服务器IP:6099（已重新生成token，见上方输出）"
        fi
        ;;
esac
echo "====================================="
echo "常用管理命令："
echo "1. 查看容器状态：docker ps -a | grep -E 'astrbot|napcat'"
echo "2. 重启服务：docker restart astrbot napcat"
echo "3. 查看日志：docker logs -f astrbot（或 napcat）"
echo "4. 查看Napcat token：docker logs napcat | grep '🔑 token='"
echo "5. 停止服务：docker stop astrbot napcat"
echo "====================================="
echo "AstrBot官方文档：https://astrbot.app"
echo "感谢您使用本脚本，祝您bot使用愉快！"
echo "服务来自-轻雪云：https://qxue.top"
echo "====================================="